package com.example.music_project

import android.app.Notification
import android.app.NotificationChannel
import android.app.NotificationManager
import android.app.PendingIntent
import android.app.Service
import android.content.Context
import android.content.Intent
import android.media.MediaPlayer
import android.os.Binder
import android.os.IBinder
import android.provider.MediaStore
import android.util.Log
import androidx.core.app.NotificationCompat

class MusicService : Service() {
    companion object {
        const val Commond = "Operate"
        const val Channel_ID = "Music_Channel"
        const val Notification_ID = 1
    }

    val TAG = "MusicService"
    val mediaPlayer = MediaPlayer()
    val musicList = mutableListOf<String>()
    val musicNameList = mutableListOf<String>()
    var current = 0
    var isPause = false
    var isPrepared = false
    val binder = MusicBinder()

    inner class MusicBinder : Binder() {
        val musicName: String
            get() = if (musicNameList.isNotEmpty()) musicNameList[current] else "No Music"
        var currentPosition: Int
            get() = if (isPrepared) mediaPlayer.currentPosition else 0
            set(value) {
                if (isPrepared) mediaPlayer.seekTo(value)
            }
        val duration: Int
            get() = if (isPrepared) mediaPlayer.duration else 0
        val size: Int
            get() = musicList.size
        val currentIndex: Int
            get() = current
    }

    override fun onBind(intent: Intent): IBinder? {
        return binder
    }

    override fun onCreate() {
        super.onCreate()
        getMusicList()
        mediaPlayer.setOnPreparedListener {
            isPrepared = true
            it.start()
            showNotification(musicNameList[current])
        }
        mediaPlayer.setOnCompletionListener {
            current++
            if (current >= musicList.size) {
                current = 0
            }
            play()
        }
    }

    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
        val operate = intent?.getIntExtra(Commond, 1) ?: 1
        when (operate) {
            1 -> play()
            2 -> pause()
            3 -> stop()
            4 -> next()
            5 -> prev()
        }
        return super.onStartCommand(intent, flags, startId)
    }

    fun play() {
        if (musicList.isEmpty()) {
            Log.e(TAG, "Music list is empty")
            return
        }
        val path = musicList[current]
        mediaPlayer.reset()
        isPrepared = false
        try {
            mediaPlayer.setDataSource(path)
            mediaPlayer.prepareAsync()
        } catch (e: Exception) {
            e.printStackTrace()
        }
    }

    fun pause() {
        if (isPause) {
            mediaPlayer.start()
            isPause = false
        } else {
            mediaPlayer.pause()
            isPause = true
        }
    }

    fun stop() {
        mediaPlayer.stop()
        stopSelf()
    }

    fun next() {
        current++
        if (current >= musicList.size) {
            current = 0
        }
        play()
    }

    fun prev() {
        current--
        if (current < 0) {
            current = musicList.size - 1
        }
        play()
    }

    fun getMusicList() {
        val projection = arrayOf(
            MediaStore.Audio.Media.DATA,
            MediaStore.Audio.Media.TITLE
        )
        val cursor = contentResolver.query(
            MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
            projection,
            MediaStore.Audio.Media.IS_MUSIC + "!= 0",
            null,
            null
        )
        if (cursor != null) {
            while (cursor.moveToNext()) {
                val musicPath = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DATA))
                musicList.add(musicPath)
                val musicName = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.TITLE))
                musicNameList.add(musicName)
                Log.d(TAG, "getMusicList : $musicPath name : $musicName")
            }
            cursor.close()
        } else {
            Log.e(TAG, "Cursor is null")
        }
        Log.d(TAG, "Total music files found: ${musicList.size}")
    }

    private fun showNotification(songName: String) {
        val notificationManager: NotificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
        val builder: NotificationCompat.Builder
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
            val channel = NotificationChannel(Channel_ID, "Music Channel", NotificationManager.IMPORTANCE_DEFAULT)
            notificationManager.createNotificationChannel(channel)
            builder = NotificationCompat.Builder(this, Channel_ID)
        } else {
            builder = NotificationCompat.Builder(this)
        }
        val intent = Intent(this, MainActivity::class.java)
        val pendingIntent = PendingIntent.getActivity(
            this,
            1,
            intent,
            PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
        )
        val notification: Notification = builder.setSmallIcon(R.drawable.ic_notification)
            .setContentTitle("Now Playing")
            .setContentText(songName)
            .setContentIntent(pendingIntent)
            .build()
        notificationManager.notify(Notification_ID, notification)
    }
}